#ifndef _STR_UTIL_H_
#define _STR_UTIL_H_

#include <stddef.h>

// Return the string with only its first character capitalized.
char *str_capitalize(char *dst);

// Return the number of non-overlapping occurrences of substring sub in the range [start, end]
int str_count(const char *start, const char *end, const char *sub);
#define str_count_x(start, sub) str_count((start), NULL, (sub))

// Return True if the string ends with the specified suffix, otherwise return False.
int str_endwith(const char *start, const char *end, const char *suffix);
#define str_endwith_x(start, suffix) str_endwith((start), NULL, (suffix))

// Return True if string starts with the prefix, otherwise return False.
int str_startwith(const char *start, const char *end, const char *prefix);
#define str_startwith_x(start, prefix) str_startwith((start), NULL, (prefix))

// Return the lowest index in the string where substring sub is found,
// such that sub is contained in the range [start, end].
// Return -1 if sub is not found.
int str_find(const char *start, const char *end, const char *sub);
#define str_find_x(start, sub) str_find((start), NULL, (sub))

// Return true if all characters in the string are alphanumeric and there is at least one character,
// false otherwise.
int str_isalnum(const char *src);

// Return true if all characters in the string are alphabetic and there is at least one character,
// false otherwise.
int str_isalpha(const char *src);

// Return true if all characters in the string are digits and there is at least one character,
// false otherwise.
int str_isdigit(const char *src);

// Return true if all cased characters in the string are lowercase and there is at least one cased character,
// false otherwise.
int str_islower(const char *src);

// Return true if there are only whitespace characters in the string and there is at least one character,
// false otherwise.
int str_isspace(const char *src);

// Return true if all cased characters in the string are uppercase and there is at least one cased character,
// false otherwise.
int str_isupper(const char *src);

// Return a string which is the concatenation of the strings in the table.
// The separator between elements is the string join.
char *str_join(const char **table, size_t size, char *dst, size_t offset, const char *join);

// Return the string converted to lowercase.
char *str_lower(char *dst);

// Return the string converted to uppercase
char *str_upper(char *dst);

// Return a copy of the string with leading characters removed.
// The charset argument is a string specifying the set of characters to be removed.
// If charset is NULL, the method defaults to removing whitespace.
// e.g.
// str_lstrip('   spacious   ', NULL) => 'spacious   '
// str_lstrip('www.example.com', 'cmowz.') => 'example.com'
char *str_lstrip(char *dst, const char *charset);
#define str_lstrip_x(dst) str_lstrip((dst), NULL)

// Return a string with all occurrences of substring old replaced by new.
// If the argument count is given, only the first count occurrences are replaced.
char *str_replace(char *dst, const char *src, const char *olds, const char *news, int count);
#define str_replace_x(dst, src, olds, news) str_replace((dst), (src), (olds), (news), -1)

// Return the highest index in the string where substring sub is found,
// such that sub is contained within s[start,end].
// Optional arguments start and end are interpreted as in slice notation.
// Return -1 on failure.
int str_rfind(const char *start, const char *end, const char *sub);
#define str_rfind_x(start, sub) str_rfind((start), NULL, (sub))

// Return a the string with trailing characters removed.
// The charset argument is a string specifying the set of characters to be removed.
// If charset is NULL, the method defaults to removing whitespace.
// The chars argument is not a suffix; rather, all combinations of its values are stripped:
// e.g.
// str_rstrip('   spacious   ', NULL) => '   spacious'
// str_rstrip('mississippi', 'ipz') => 'mississ'
char *str_rstrip(char *dst, const char *charset);
#define str_rstrip_x(dst) str_rstrip((dst), NULL)

// Return a list of the words in the string, using sep as the delimiter string.
// If maxsplit is given, at most maxsplit splits are done, -1 means no limit
char **str_split(char **table, size_t* size, const char *src, const char *separator, const int maxsplit);
#define str_split_x(table, sz, src, separator) str_split((table), (sz), (src), (separator), -1)

// Return a string with the leading and trailing characters removed.
// The chars argument is a string specifying the set of characters to be removed.
// If charset is NULL, the chars argument defaults to removing whitespace.
char *str_strip(char *dst, const char *charset);
#define str_strip_x(dst) str_strip((dst), NULL)

// Return a copy of the string with uppercase characters converted to lowercase and vice versa.
char *str_swapcase(char *dst);

// Return a string where all characters occurring in the optional argument deletechars are removed,
// and the remaining characters have been mapped through the given translation table(from, to)
char *str_translate(char *dst, const char *src, const char *from, const char *to, const char *deletechars);
#define str_translate_delete(dst, src, delete) str_translate((dst), (src), NULL, NULL, (deletechars))

#endif // End _STR_UTIL_H_
